package ui.patient_registration.controller;

import database.dao.DaoFactory;
import database.dao.PatientDao;
import patient.Patient;
import ui.patient_card.view.PatientCardDialog;
import ui.patient_registration.models.PatientTableModel;
import ui.patient_registration.view.patient_data.FormPanel;
import util.Const;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.StringTokenizer;

public class RegistrationController {
    private static RegistrationController ourInstance = new RegistrationController();

    private PatientDao patientDao;

    private FormPanel formPanel;
    private JTable patientTable;
    private PatientTableModel patientTableModel;
    private JTextField searchTF;

    private RegistrationController() {
        patientDao = new PatientDao(new DaoFactory());
    }

    public static RegistrationController getInstance() {
        return ourInstance;
    }

    public void onSaveClick() {
        int selectedRowIndex = patientTable.getSelectedRow();

        if (formPanel.getImieTF().getText().equals("") || formPanel.getNazwiskoTF().getText().equals("")) {
            JOptionPane.showMessageDialog(
                    null,
                    Const.Strings.NAME_AND_SURNAME_REQUIRED,
                    Const.Strings.INFORMATION,
                    JOptionPane.INFORMATION_MESSAGE);
        } else {
            if (selectedRowIndex != -1) {
                int patientId = patientTableModel.getPatientByRow(selectedRowIndex).getId();
                patientDao.updatePatient(patientId, formPanel.getPatientFromFields());
                Patient patient = formPanel.getPatientFromFields();
                patient.setId(patientId);
                patientTableModel.editPatientByRow(patient, selectedRowIndex);
                patientTable.clearSelection();
                formPanel.clearForm();
            } else {
                Patient patient = formPanel.getPatientFromFields();
                patientDao.savePatient(patient);
                patientTableModel.addPatient(patient);
                formPanel.clearForm();
            }
        }
    }

    public void onCancelClick() {
        formPanel.clearForm();
    }

    public void onSearchClickListener() {
        StringTokenizer tokenizer = new StringTokenizer(searchTF.getText());
        if (searchTF.getText().equals("")) {
            patientTableModel.resetFilter();
            patientTableModel.sortPatients();
        }
        else if (tokenizer.countTokens() == 1) {
            String token = tokenizer.nextToken();
            patientTableModel.refilter(token, token);
        }
        else if (tokenizer.countTokens() == 2) {
            String imie = tokenizer.nextToken();
            String nazwisko = tokenizer.nextToken();
            patientTableModel.refilter(imie, nazwisko);
        } else {
            JOptionPane.showMessageDialog(
                    null,
                    Const.Strings.NAME_REQUIRED,
                    Const.Strings.INFORMATION,
                    JOptionPane.INFORMATION_MESSAGE);
        }
    }

    public void onPatientCardClick() {
        int numOfRow = patientTable.getSelectedRow();
        if (numOfRow != -1) {
            PatientCardDialog patientCardDialog = new PatientCardDialog(patientTableModel.getPatientByRow(numOfRow));
            patientCardDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            patientCardDialog.setVisible(true);
        } else {
            JOptionPane.showMessageDialog(
                    null,
                    Const.Strings.ROW_PATIENT_CARD_REQUIRED,
                    Const.Strings.INFORMATION,
                    JOptionPane.INFORMATION_MESSAGE);
        }
    }

    public void onAddClick() {
        patientTable.clearSelection();
        formPanel.clearForm();
    }

    public void onDeleteClick() {
        int numOfRow = patientTable.getSelectedRow();
        if (numOfRow != -1) {
            Patient patientToDelete = patientTableModel.getPatientByRow(numOfRow);
            patientTableModel.removeRow(numOfRow);
            patientDao.deletePatient(patientToDelete);
            formPanel.clearForm();
        } else {
            JOptionPane.showMessageDialog(
                    null,
                    Const.Strings.ROW_DELETE_REQUIRED,
                    Const.Strings.INFORMATION,
                    JOptionPane.INFORMATION_MESSAGE);
        }
    }

    public void fillFormByPatient(Patient patient) {
        formPanel.fillForm(patient);
    }

    public void setPatientTable(JTable patientTable) {
        this.patientTable = patientTable;
    }

    public void setPatientTableModel(PatientTableModel patientTableModel) {
        this.patientTableModel = patientTableModel;
    }

    public void setFormPanel(FormPanel formPanel) {
        this.formPanel = formPanel;
    }

    public ActionListener getSaveBtnListener() {
        return new SaveBtnListener();
    }

    public ActionListener getCancelBtnListener() {
        return new CancelBtnListener();
    }

    public ActionListener getSearchBtnListener() {
        return new SearchBtnLiestener();
    }

    public ActionListener getPatientCardBtnListener() {
        return new PatientCardBtnListener();
    }

    public ActionListener getAddBtnListener() {
        return new AddBtnListener();
    }

    public ActionListener getDeleteBtnListener() {
        return new DeleteBtnListener();
    }

    public ListSelectionListener getTableListListener() {
        return new TableListListener();
    }

    public void setSearchTF(JTextField searchTF) {
        this.searchTF = searchTF;
    }

    class SaveBtnListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            onSaveClick();
        }
    }

    class CancelBtnListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            onCancelClick();
        }
    }

    class SearchBtnLiestener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            onSearchClickListener();
        }
    }

    class PatientCardBtnListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            onPatientCardClick();
        }
    }

    class AddBtnListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            onAddClick();
        }
    }

    class DeleteBtnListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            onDeleteClick();
        }
    }

    class TableListListener implements ListSelectionListener {
        public void valueChanged(ListSelectionEvent e) {
            int rowIndex = patientTable.getSelectedRow();

            if (rowIndex >= 0) {
                Patient patient = patientTableModel.getPatientByRow(rowIndex);
                fillFormByPatient(patient);
            }
        }
    }
}
